package com.ezhou.hy.common.xml;

import java.io.IOException;
import java.io.Reader;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import com.ezhou.hy.exception.DaoException;


/**
 * <p>Title: </p>
 * <p>Description: </p>
 * <p>CopyRight:Copyright (c) 2008.12 </p>
 * <p>Company: </p>
 * @author Haiger
 * @version 1.0
 */
public class XMLDaoManager {
	private static Logger log = Logger.getLogger(XMLDaoManager.class);
	
	private static final String DAO_CONFIG_ELEMENT = "daoconfig";
	private static final String CONTEXT_ELEMENT = "context";
	private static final String DAO_ELEMENT = "dao";
	
	private Properties daoMap = null;
	
	
	public XMLDaoManager(){
	}
	
	
	//parse XML NODE
	public Properties getDaoProperties(Reader reader) throws DaoException{	
		try{
			Document doc = getDoc(reader);
			Element root = (Element) doc.getLastChild();
			String rootName = root.getNodeName();
			
			if(!DAO_CONFIG_ELEMENT.equals(rootName)){
				log.error("daoConfig.XML Errors.the root tag must be "+DAO_CONFIG_ELEMENT);
				throw new IOException("daoConfig.XML Errors.the root tag must be "+DAO_CONFIG_ELEMENT);
			}
			
			NodeList children = root.getChildNodes();
			for(int i = 0;i < children.getLength();i++){
				Node child = children.item(i);
				if(child.getNodeType() == Node.ELEMENT_NODE){
					if(CONTEXT_ELEMENT.equals(child.getNodeName())){
						daoMap = parseContext((Element)child);	
					}				
				}
			}
			
		}catch(Exception e){
			log.error("DaoConfig.XML Paser Errors. Cause:"+e.toString());
			throw new DaoException("DaoConfig.XML Paser Errors. Cause:"+e.toString());
		}
		
		return daoMap;
	}
	
	private Properties parseContext(Element contextElement){
		NodeList children = contextElement.getChildNodes();
		Properties attributes = new Properties();
		for(int i = 0;i < children.getLength();i++){
			Node child = children.item(i);
			NamedNodeMap attributeNodes = child.getAttributes();
			if(child.getNodeType() == Node.ELEMENT_NODE){
				if(DAO_ELEMENT.equals(child.getNodeName())){
					String iface = attributeNodes.getNamedItem("interface").getNodeValue();
					String impl   = attributeNodes.getNamedItem("implements").getNodeValue();
					
					attributes.put(iface, impl);
				}
			}
		}
		
		return attributes;
	}
/*	
	private Properties parseDao(Element element){
		Properties attributes = new Properties();
		if(element.getNodeType() == Node.ELEMENT_NODE){
			if(DAO_ELEMENT.equals(element.getNodeName())){
				attributes = parseAttributes(element);
			}
		}
		
		return attributes;
	}
	
	private Properties parseAttributes(Node n){
		Properties attributes = new Properties();
		NamedNodeMap attributeNodes = n.getAttributes();
//		String daoIfaceName = attributeNodes.getNamedItem("interface").getNodeValue();
//		String daoImplURI = attributeNodes.getNamedItem("implements").getNodeValue();
//    	System.out.println("iface:"+daoIfaceName+"%%%  impl:"+daoImplURI);
//		attributes.put(daoIfaceName, daoImplURI);
//		System.out.println("8888888888");
		for(int i = 0; i < attributeNodes.getLength(); i++){
			Node attribute = attributeNodes.item(i);
//			System.out.println(attribute.getNodeName()+attribute.getNodeValue());
			attributes.put(attribute.getNodeName(), attribute.getNodeValue());
		}
		return attributes;
	}
*/
	
	private Document getDoc(Reader reader){
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setNamespaceAware(false);
			dbf.setIgnoringComments(true);
			dbf.setIgnoringElementContentWhitespace(true);
		    dbf.setCoalescing(false);
		    dbf.setValidating(true);
		    dbf.setExpandEntityReferences(false);
			
			DocumentBuilder builder = dbf.newDocumentBuilder();
			
			Document doc = builder.parse(new InputSource(reader));
			
			return doc;
		} catch (Exception e) {
			throw new RuntimeException("XML Paraser Errors. Cause"+e);
		}	
	}

}
